﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using DevExpress.Xpf.Docking;
using SQLQuery.UI;
using SQLQuery.ViewModel;
using DevExpress.Xpf.Bars;
using DevExpress.Xpf.Ribbon;
using DevExpress.Utils;
using SQLQuery.Common;
using QueryResource.ViewModel;
using DevExpress.Xpf.Core;
using SQLQuery.UI.Comparsion;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Linq;

namespace SQLQuery
{
    /// <summary>
    /// RibbonMainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class RibbonMainWindow : DXWindow
    {

        public RibbonMainWindow()
        {
            InitializeComponent();
            //WindowHelper.RepairWindowBehavior(this);
            Init();
            this.Closed += new EventHandler(MainWindow_Closed);
        }




        //主界面
        public MainViewModel ViewModel { get; set; }
        //树
        public DBTreeViewModel TreeViewModel { get; set; }
        //数据对比
        public DataComparsionViewModel ComparsionViewModel { get; set; }

        public BitmapImage GetImageSource(string itemPath)
        {
            BitmapImage img = new BitmapImage();
            img.BeginInit();

            img.CacheOption = BitmapCacheOption.OnLoad;
            img.UriSource = new Uri("pack://application:,,,/" + System.Reflection.Assembly.GetExecutingAssembly().FullName + ";component/" + itemPath);
            img.EndInit();
            img.Freeze();
            return img;
        }

        #region
        private void dockManager_DockItemClosed(object sender, DevExpress.Xpf.Docking.Base.DockItemClosedEventArgs e)
        {

            LayoutPanel panel = e.Item as LayoutPanel;
            if (e.Item is LayoutGroup)
            {
                panel = (e.Item as LayoutGroup).Items[0] as LayoutPanel;
            }
            SQLControl sql = panel.Content as SQLControl;
            if (sql != null)
            {
                sql.ViewModel.AppendLogAction = null;
                sql.ViewModel.AppendDataAction = null;
                sql.ViewModel = null;
                sql.RemoveFile();

            }
            else
            {
                GridViewControl control = panel.Content as GridViewControl;
                if (control != null)
                {
                    control.AppendLogAction = null;
                    control.AppendDataSucess = null;
                    control.AppendSqlContent = null;
                }
            }
        }
       
      
        void MainWindow_Closed(object sender, EventArgs e)
        {
            if (!isUpdate)
            {
                SaveData();
            }
        }
        private void SaveData()
        {
            DocumentPanel dp = this.sqlcontrol.Tag as DocumentPanel;
            if (dp != null && dp.Caption.IndexOf('*') > 0)
            {
                this.sqlcontrol.SaveFile(System.AppDomain.CurrentDomain.BaseDirectory + "\\文档.txt");
            }
        }
        #endregion

        #region 工具栏
        //皮肤
        protected virtual void OnThemeDropDownGalleryInit(object sender, DropDownGalleryEventArgs e)
        {
            Gallery gallery = e.DropDownGallery.Gallery;
            gallery.AllowHoverImages = false;
            gallery.IsItemCaptionVisible = true;
            gallery.ItemGlyphLocation = Dock.Top;
            gallery.IsGroupCaptionVisible = DefaultBoolean.True;
        }
        protected virtual void OnThemeItemClick(object sender, GalleryItemEventArgs e)
        {
            string themeName = (string)e.Item.Caption;
            themeName = themeName.Replace(" ", string.Empty);
            ViewModel.SkinChanged(this,themeName);
        }
        //新建数据源
        private void CreateDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.CreateDBExecuted();
        }
        //拷贝字段名
        private void CopyFieldName_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.CopyFieldNameExecuted();
        }
        //格式刷
        private void TxtFormat_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.TxtFormatCanExecute();
        }
        private void TxtFormat_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.TxtFormatExecuted();
        }
        //打开文件
        private void FileOpen_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.FileOpenExecuted();
        }
        //另存为文件
        private void FileSaveAs_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.FileSaveAsExecuted();
        }
        private void FileSaveAs_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.FileSaveAsCanExecute();
        }
        //保存文件
        private void FileSave_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.FileSaveCommand.Execute(null);
        }
        private void FileSave_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.FileSaveCommand.CanExecute(null);
        }
        //运行
        private void RunSQL_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.RunSqlExecuted();
           
        }
        private void RunSQL_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.RunSqlCanExecute();
        }
        //删除数据源
        private void DelDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TreeViewModel.DeleteCommand.Execute(TreeViewModel.SelectedItem);
        }
        private void DelDB_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = TreeViewModel.DeleteCommand.CanExecute(null);
            }
        }
        //连接
        private void ConnectionDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TreeViewModel.ConnectDBCommand.Execute(TreeViewModel.SelectedItem);
        }
        private void ConnectionDB_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = TreeViewModel.ConnectDBCommand.CanExecute(null);
            }
        }
        //断开连接
        private void UnConnectionDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TreeViewModel.UnConnectDBCommand.Execute(TreeViewModel.SelectedItem);
        }
        private void UnConnectionDB_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = TreeViewModel.UnConnectDBCommand.CanExecute(null);
            }
        }
        //清空
        private void TxtClear_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.ClearCommand.Execute(null);
        }
        private void TxtClear_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = ViewModel.ClearCommand.CanExecute(null);
            }
        }

        //更新
        bool isUpdate = false;      //此标志为了 防止关闭窗体时 再次生成数据文件
        private void bUpdate_ItemClick(object sender, ItemClickEventArgs e)
        {
            isUpdate =  UpdateHelper.Update(() => {
                SaveData();
            });
            if (isUpdate)
            {
                Application.Current.Shutdown();
            }
        }

        #region 数据对比
        private void ComConnection_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DataComparsionControl control = ShowDataComparsionWindow("数据对比");

            control.Connection_Click();
            this.dockManager.LayoutController.Activate(documentLog);
        }
       
        private void Comparsion_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl ctrl = panel.Content as DataComparsionControl;
                if (ctrl.ViewModel.DataSourceList.Count > 0 && !ctrl.ViewModel.IsBusy)
                {
                    e.CanExecute = true;
                }
                else
                {
                    e.CanExecute = false;
                }
            }
            else
            {
                e.CanExecute = false;
            }
        }
        private void ComRefresh_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.Refresh();
            }
        }
        private void ComData_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.Comparsion_Click();
            }
        }
        private void ComSync_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.ViewModel.SyncData();
            }
        }
        private void ComRowCount_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.ViewModel.SyncRowCount();
            }
        }
        private void ComExportoRow_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.ButtonExport_Click();
            }
        }
        private void ComPartExportRow_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.ButtonPartExport_Click();
            }
        }
        private void ComRemoveTable_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel != null)
            {
                DataComparsionControl control = panel.Content as DataComparsionControl;
                control.ViewModel.RemoveData();
            }
        }
        private void ComRowContent_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
             DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
             if (panel != null)
             {
                 DataComparsionControl control = panel.Content as DataComparsionControl;
                 control.ButtonRowContent_Click();
             }
        }
        #endregion
        #endregion
      

        #region
        #region 交互
     
        private void ShowNewWindowLoadFile(string caption, string content,bool isFile)
        {
            DocumentPanel panel = new DocumentPanel();
            if (documentGroup.Items.FirstOrDefault(o => o.Caption == caption) != null)
            {
                panel.Caption = caption + new Random().Next(5,9);
            }
            else
            {
                panel.Caption = caption;
            }
            panel.AllowRename = false;
            SQLControl control = new SQLControl();
            control.ViewModel.AppendLogAction = ShowLog;
            control.ViewModel.AppendDataAction = ShowDS;
           
            control.Tag = panel;
            panel.Content = control;
           
            this.documentGroup.Items.Add(panel);
            
            this.dockManager.LayoutController.Activate(panel, true);
            if (isFile)
            {
                control.Init(false);
                control.LoadFile(content);
            }
            else
            {
                control.Init(false, false);
                control.IsNewDocument = true;
                control.LoadText(content);
            }

            SendKeys.Press(Key.Up);

          
        }
        /// <summary>
        /// 弹出数据对比窗体（唯一）
        /// </summary>
        /// <param name="caption"></param>
        private DataComparsionControl ShowDataComparsionWindow(string caption)
        {
            DocumentPanel panel = GetDocumentControl<DataComparsionControl>();
            if (panel == null)
            {
                panel = new DocumentPanel();
                panel.Caption = caption;

                DataComparsionControl dc = new DataComparsionControl();
                dc.ViewModel.AppendLogAction = ShowLog;
                
                panel.Content = dc;
                this.documentGroup.Items.Add(panel);
            }
            this.dockManager.LayoutController.Activate(panel);
            return panel.Content as DataComparsionControl;
        }
        private void ShowSQL(string sql, bool isRun, bool isNewLine)
        {
            if (!this.documentSQL.IsActive)
            {
                this.dockManager.LayoutController.Activate(documentSQL);
            }
            this.sqlcontrol.ViewModel.ExecAppendCmd(sql, isRun, isNewLine);
        }

        private void ShowLog(string msg, Color errorColor)
        {
            if (errorColor != Colors.Black)
            {
                this.InvokeEx(new Action(() =>
                {
                    if (!this.documentLog.IsActive)
                    {
                        this.dockManager.LayoutController.Activate(documentLog);
                    }
                }));
            }
            this.logcontrol.ScrollToEnd();
            this.logcontrol.WriteLog(msg, errorColor);
        }

        private void ShowDS(string sql)
        {
            this.BeginInvokeEx(new Action(() =>
            {
                GridViewControl control = GetNoBusyGridControl(true);
                if (control != null)
                {
                    control.DataBind(sql);
                }
                else
                {
                    LayoutGroup group = this.documentDS.Parent as LayoutGroup;
                   if (group == null)
                   {
                       GridViewControl gridcontrol = documentDS.Content as GridViewControl;
                       if (gridcontrol.IsBusy)
                       {
                           ShowLog("正在查询中……", Colors.Blue);
                       }
                       else
                       {
                           gridcontrol.DataBind(sql);
                       }
                   }
                   else
                   {
                       ////新增一个窗体
                       LayoutPanel panel = new LayoutPanel();
                       panel.Caption = "数据";

                       control = new GridViewControl();
                       control.AppendLogAction = ShowLog;
                       control.AppendDataSucess = ShowDataSucess;
                       control.AppendSqlContent = ShowNewWindowLoadFile;
                       panel.Content = control;
                       group.Items.Add(panel);
                       this.dockManager.LayoutController.Activate(panel);
                       control.DataBind(sql);
                   }
                }
            }));
        }

        private void ShowDBInfo(string ip, string dbname, string userid)
        {
            this.BeginInvokeEx(new Action(() =>
            {
                this.lbIPname.Content = "数据库IP：" + ip;
                this.lbDBname.Content = string.Format("数据库名称:{0}", dbname.Replace("_", "__"));
                this.lbUserId.Content = "当前用户:" + userid;
            }), null);
        }

        private void ShowFieldCaption(string caption)
        {
            this.lbFieldName.BeginInvokeEx(new Action(() =>
            {
                this.lbFieldName.Content = "说明：" + caption;
            }), null);
        }

        private void ShowDataSucess(GridViewControl control)
        {
            LayoutPanel panel = control.Tag as LayoutPanel;
            if (panel != null)
            {
                this.dockManager.LayoutController.Activate(panel);
            }
        }

        #endregion
        /// <summary>
        /// 查找Document 中存在的控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        private DocumentPanel GetDocumentControl<T>() where T : class
        {
            BaseLayoutItemCollection collection = (this.documentSQL.Parent as LayoutGroup).Items;
            foreach (DocumentPanel panel in collection)
            {
                T control = panel.Content as T;
                if (control != null)
                {
                    return panel; 
                }
            }
            return null;
        }
        /// <summary>
        /// 获得当前激活的 Document
        /// </summary>
        /// <returns></returns>
        private DocumentPanel GetActiveSQLControl(ref SQLControl control)
        {
            BaseLayoutItemCollection collection = (this.documentSQL.Parent as LayoutGroup).Items;
            if (collection.Count == 1)
            {
                DocumentPanel panel =collection[0] as DocumentPanel;
                SQLControl sqlcontrol = panel.Content as SQLControl;
                if (sqlcontrol != null)
                {
                    control = sqlcontrol;
                    return panel;
                }
            }
            else
            {
                foreach (DocumentPanel panel in collection)
                {
                    if (!panel.IsActive)
                        continue;
                    SQLControl sqlcontrol = panel.Content as SQLControl;
                    if (sqlcontrol != null)
                    {
                        control = sqlcontrol;
                        return panel;
                    }
                }
            }
            control = this.sqlcontrol;
            return this.documentSQL;
        }
        /// <summary>
        /// 返回一个闲置的Grid 如果没有 则返回NUll
        /// </summary>
        /// <returns></returns>
        private GridViewControl GetNoBusyGridControl(bool isActive)
        {
            LayoutGroup group = this.documentDS.Parent as LayoutGroup;
            GridViewControl gc = null;
            if (group != null)
            {
                List<LayoutPanel> removes = new List<LayoutPanel>();
                foreach (LayoutPanel panel in group.Items)
                {
                    GridViewControl gridcontrol = panel.Content as GridViewControl;
                    if (gridcontrol != null)
                    {
                        if (!gridcontrol.IsBusy)
                        {
                            if (isActive)
                            {
                                this.dockManager.LayoutController.Activate(panel);
                            }
                            if (gc != null)
                            {
                                removes.Add(panel);
                            }
                            else
                            {
                                gc = gridcontrol;
                            }
                        }
                    }
                }
                removes.ForEach(o => group.Items.Remove(o));
            }
            return gc;
        }
        /// <summary>
        /// 获取当前激活的SQL编辑框
        /// </summary>
        /// <returns></returns>
        private SQLControl GetActiveSQLControl()
        {
            SQLControl sql = null;
            GetActiveSQLControl(ref sql);
            return sql;
        }
        #endregion

        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {

            ViewModel = new MainViewModel(this.dbtreeview.ViewModel);
            TreeViewModel = this.dbtreeview.ViewModel;
            DataContext = this;

            ViewModel.GetActiveSqlControl = GetActiveSQLControl;
            ViewModel.GetActiveSqlPanel += GetActiveSQLControl;
            ViewModel.ShowNewWindowLoadFile = ShowNewWindowLoadFile;

            TreeViewModel.AppendSqlAction = ShowSQL;
            TreeViewModel.AppendLogAction = ShowLog;
            TreeViewModel.AppendWindow = (caption, content) => ShowNewWindowLoadFile(caption, content, false);
            TreeViewModel.AppendDBInfo = ShowDBInfo;
            TreeViewModel.AppendFieldCaption = ShowFieldCaption;
            TreeViewModel.AppendSqlContent = ShowNewWindowLoadFile;

            this.sqlcontrol.ViewModel.AppendLogAction = ShowLog;
            this.sqlcontrol.ViewModel.AppendDataAction = ShowDS;

            this.gridviewcontrol.AppendLogAction = ShowLog;
            this.gridviewcontrol.AppendDataSucess = ShowDataSucess;
            this.gridviewcontrol.AppendSqlContent = ShowNewWindowLoadFile;

            ComparsionViewModel = new DataComparsionViewModel();
            ComparsionViewModel.AppendLogAction = ShowLog;
            ComparsionViewModel.ViewInvoke = act => this.InvokeEx(act);

            //初始化
            this.dbtreeview.Init();
            this.sqlcontrol.Init(true);
            ViewModel.ReadTheme(this);

            if(Directory.Exists(System.AppDomain.CurrentDomain.BaseDirectory + "\\Temporary"))
            {
                foreach(string file in Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory + "\\Temporary","*.txt"))
                {
                    ShowNewWindowLoadFile(Path.GetFileName(file), File.ReadAllText(file), false);
                }
            }

            UpdateTip();

        }

        /// <summary>
        /// 获取更新信息
        /// </summary>
        private void UpdateTip()
        {
            Func<string> action = () =>
            {
                System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                try
                {
                    if (UpdateHelper.IsDown(name.Version.ToString(), System.IO.Path.GetFileName(name.CodeBase)))
                    {
                        return "亲，又有新版本了，请记得更新哦。";
                    }
                    else
                    {
                        return "当前版本:" + name.Version.ToString();
                    }
                }
                catch
                {
                    return "当前版本:" + name.Version.ToString();
                }
            };
            Task<string>.Factory.FromAsync(action.BeginInvoke, action.EndInvoke, null)
                .ContinueWith(t => this.lbUpdateInfo.InvokeEx(new Action(() =>
                                                                             {
                                                                                 this.lbUpdateInfo.Content = t.Result;
                                                                             })));
        }

   
    }
}
